package util

import (
	"encoding/json"
	"os"
	"path"
	"path/filepath"
	"strings"
)

// GetFileName 获取路径中的文件名
func GetFileName(file string) string {
	_, file = filepath.Split(file)
	return file
}

// TruncateExtend 去掉文件扩展名
func TruncateExtend(file string) string {
	if len(file) > 0 {
		ext := path.Ext(file)
		if len(ext) > 0 {
			return strings.TrimSuffix(file, ext)
		}
	}
	return file
}

// GetFileBaseName 获取路径中的文件名，不含扩展名
func GetFileBaseName(file string) string {
	file = GetFileName(file)
	file = TruncateExtend(file)
	return file
}

// GetProgramFileAbsPath 获取当前可执行文件绝对路径
func GetProgramFileAbsPath() (string, error) {
	exe, err := os.Executable()
	if err != nil {
		return "", err
	}
	exe = filepath.ToSlash(exe)
	return exe, nil
}

// MustGetProgramFileAbsPath 获取当前可执行文件绝对路径
func MustGetProgramFileAbsPath() string {
	absPath, err := GetProgramFileAbsPath()
	if err != nil {
		panic(err)
	}
	return absPath
}

// GetProgramFileName 获取当前可执行文件名（含扩展名）
func GetProgramFileName() (string, error) {
	absPath, err := GetProgramFileAbsPath()
	if err != nil {
		return "", err
	}
	_, file := filepath.Split(absPath)
	return file, nil
}

// MustGetProgramFileName 获取当前可执行文件名（含扩展名）
func MustGetProgramFileName() string {
	file, err := GetProgramFileName()
	if err != nil {
		panic(err)
	}
	return file
}

// GetProgramFileBaseName 获取当前可执行文件名（不含扩展名）
func GetProgramFileBaseName() (string, error) {
	file, err := GetProgramFileName()
	if err != nil {
		return "", err
	}
	file = TruncateExtend(file)
	return file, nil
}

// MustGetProgramFileBaseName 获取当前可执行文件名（不含扩展名）
func MustGetProgramFileBaseName() string {
	file, err := GetProgramFileBaseName()
	if err != nil {
		panic(err)
	}
	return file
}

// IsDirOrFileExist 如果目录不存在创建指定目录
func IsDirOrFileExist(path string) error {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return err
		}
		panic(err)
	}
	return nil
}

// MkDir 如果目录不存在创建指定目录
func MkDir(path string) error {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return os.MkdirAll(path, os.ModePerm)
		}
		return err
	}
	return nil
}

// MustMkDir 如果目录不存在创建指定目录
func MustMkDir(path string) {
	if err := MkDir(path); err != nil {
		panic(err)
	}
}

// Walk 遍历目录
func Walk(dir string, extend string, whiteList []string, blackList []string, fn func(path string, info os.FileInfo, name string, isInBlackList bool) (continued bool)) (err error) {
	absDir, err := filepath.Abs(dir)
	if err != nil {
		return
	}

	if len(whiteList) > 0 {
		for _, w := range whiteList {
			p := filepath.Join(absDir, w+"."+extend)
			info, err := os.Lstat(p)
			if err != nil {
				continue
			}
			if !fn(p, info, w, false) {
				break
			}
		}
	} else {
		ms, err := filepath.Glob(filepath.Join(absDir, "*."+extend))
		if err != nil {
			return err
		}
		for _, m := range ms {
			info, err := os.Lstat(m)
			if err != nil {
				continue
			}
			name := strings.TrimSuffix(info.Name(), "."+extend)
			var isInBlackList bool
			if len(blackList) > 0 {
				for _, n := range blackList {
					if name == n {
						isInBlackList = true
						break
					}
				}
			}
			if !fn(m, info, name, isInBlackList) {
				break
			}
		}
	}

	return
}

// LoadJSONFile 加载JSON文件
func LoadJSONFile(file string, dst any) error {
	content, err := os.ReadFile(file)
	if err != nil {
		return err
	}
	err = json.Unmarshal(content, dst)
	return err
}
